package top.ninwoo.bishe.starter.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import top.ninwoo.bishe.starter.config.ClientProperties;
import top.ninwoo.bishe.starter.entity.ContainerMonitor;
import top.ninwoo.common.entity.ContainerMonitorInfo;
import top.ninwoo.common.entity.NetworkTopology;

import javax.annotation.Resource;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class NetworkServiceImpl implements NetworkService {

    // 获取 网络的逻辑拓扑
    private final static String GET_LOGICAL_NETWORK_TOPOLOGY = "/network/getLogicalNetworkTopology?clusterId={clusterId}";

    private final static String GET_IP_LIST_BY_APP_NAME = "/network/getIpListByAppName?clusterId={clusterId}&appName={appName}";

    private final static String ENABLE_NETWORK_MONITOR = "/network/enableNetworkMonitor?clusterId={clusterId}&appName={appName}";

    private final static String CANCEL_NETWORK_MONITOR = "/network/cancelNetworkMonitor?clusterId={clusterId}&appName={appName}";
    private final static String GET_NETWORK_MONITOR_INFO = "/network/getNetworkMonitorInfo?clusterId={clusterId}&appName={appName}";
    private final static String ADD_QOS = "/network/addQos?clusterId={clusterId}&appName={appName}&maxRate={maxRate}&latency={latency}";
    @Resource
    ClientProperties clientProperties;

    @Resource
    RestTemplate restTemplate;

    @Override
    public boolean addQos(Long clusterId, String appName, String maxRate, String latency) {
        String cloudUrl = clientProperties.getCloudUrl();
        Map<String, Object> param = new HashMap<>();

        param.put("clusterId", clusterId);
        param.put("appName", appName);
        param.put("maxRate", maxRate);
        param.put("latency", latency);

        return restTemplate.getForObject("http://" + cloudUrl + ADD_QOS, Boolean.class, param);
    }

    @Override
    public NetworkTopology getLogicalNetworkTopology(Long clusterId) {
        String cloudUrl = clientProperties.getCloudUrl();

        Map<String, Object> param = new HashMap<>();

        param.put("clusterId", clusterId);

        ResponseEntity<NetworkTopology> response
                = restTemplate.getForEntity("http://" + cloudUrl + GET_LOGICAL_NETWORK_TOPOLOGY, NetworkTopology.class, param);
        if (!response.getStatusCode().is2xxSuccessful()) {
            log.error("网络请求失败");
            throw new RuntimeException("网络请求出现异常");
        }

        return response.getBody();
    }

    /**
     * 通过AppName找到对应的全部ip地址列表
     * @param clusterId
     * @param appName
     * @return
     */
    @Override
    public List<String> getIpListByAppName(Long clusterId, String appName) {
        String cloudUrl = clientProperties.getCloudUrl();

        Map<String, Object> param = new HashMap<>();

        param.put("clusterId", clusterId);
        param.put("appName", appName);

        ResponseEntity<List> response = restTemplate.getForEntity("http://" + cloudUrl + GET_IP_LIST_BY_APP_NAME,
                List.class, param);
        if(!response.getStatusCode().is2xxSuccessful()) {
            log.error("网络请求错误");
            throw new RuntimeException("网络请求错误");
        }

        return response.getBody();
    }

    /**
     * 对容器应用开启网速监控
     * @param clusterId
     * @param appName
     * @return
     */
    @Override
    public String enableNetworkMonitor(Long clusterId, String appName) {
        String cloudUrl = clientProperties.getCloudUrl();

        Map<String, Object> param = new HashMap<>();

        param.put("clusterId", clusterId);
        param.put("appName", appName);
        // 这里需要构建这个ContainerMonitor
        return restTemplate.getForObject("http://" + cloudUrl + ENABLE_NETWORK_MONITOR, String.class, param);
    }

    @Override
    public String cancelNetworkMonitor(Long clusterId, String appName) {
        String cloudUrl = clientProperties.getCloudUrl();

        Map<String, Object> param = new HashMap<>();

        param.put("clusterId", clusterId);
        param.put("appName", appName);

        return restTemplate.getForObject("http://" + cloudUrl + CANCEL_NETWORK_MONITOR, String.class, param);
    }

    /**
     * 获取容器监控的钩子程序
     * @param clusterId
     * @param appName
     * @return
     */
    @Override
    public List<ContainerMonitor> getContainerMonitors(Long clusterId, String appName) {
        String cloudUrl = clientProperties.getCloudUrl();

        Map<String, Object> param = new HashMap<>();

        param.put("clusterId", clusterId);
        param.put("appName", appName);
        // 这里需要构建这个ContainerMonitor
        //List<ContainerMonitorInfo> containerMonitorInfos
        //        = restTemplate.getForObject("http://" + cloudUrl + GET_NETWORK_MONITOR_INFO, List.class, param);
        ResponseEntity<List<ContainerMonitorInfo>> responseEntity
                = restTemplate.exchange("http://" + cloudUrl + GET_NETWORK_MONITOR_INFO,
                HttpMethod.GET, null, new ParameterizedTypeReference<List<ContainerMonitorInfo>>() {}, clusterId, appName);
        List<ContainerMonitorInfo> containerMonitorInfos = responseEntity.getBody();
        List<ContainerMonitor> containerMonitors = new ArrayList<>();
        for (ContainerMonitorInfo containerMonitorInfo : containerMonitorInfos) {
            containerMonitors.add(new ContainerMonitor(containerMonitorInfo, restTemplate));
        }
        return containerMonitors;
    }
}